iT邦幫忙

2026 iThome 鐵人賽

DAY 27
0

上一篇使用then()和catch()取得 Promise 的成功結果與失敗原因。如果非同步工作只有一步,這種寫法很直接;但需要先取得課程、再讀取詳細資料、最後更新畫面時,就會出現多段連續的then()。

async和await不會取代 Promise,而是提供另一種等待 Promise 的寫法。它能把每一步結果先放進變數,再繼續下一行,閱讀順序會比較接近一般由上往下執行的程式。

先準備一個會取得訊息的非同步函式:


async function getMessage() {
  return "讀取完成";
}

const result = getMessage();
console.log(result instanceof Promise); // true

函式內要使用await時,需要在函式前面加上async。async也會讓函式固定回傳 Promise,所以呼叫getMessage()時不會直接得到「讀取完成」,而是先得到一個 Promise。

使用then()取得訊息時,可以這樣寫:

getMessage().then((message) => {
  console.log("then 結果:", message);
});

改用await後,可以先等待結果,再使用取得的資料:

async function showMessage() {
  const message = await getMessage();
  console.log("await 結果:", message);
}

showMessage();

https://ithelp.ithome.com.tw/upload/images/20261011/20178696CGzdEeIvQf.png

await會暫停目前這個async函式,等右邊的 Promise完成後再往下走,不會讓全部 JavaScript一起停住。這就是使用async的主要原因:讓函式內可以使用await,並讓呼叫端仍然拿到 Promise,知道這個非同步函式何時完成。

目前實作使用一般的script載入 JavaScript,因此不能直接在檔案最外層寫await showMessage()。要把需要等待的流程放進async函式,再呼叫這個函式:


async function runDay21() {
  await showMessage();
  await loadLessons();
}

runDay21().catch((error) => {
  console.error("Day 21 執行失敗:", error.message);
});

https://ithelp.ithome.com.tw/upload/images/20261011/20178696IURGqh3CRd.png

如果 JavaScript是用type="module"載入,模組最外層可以使用await;不過這篇沿用前面的一般 script,所以使用runDay21()包住流程。

fetch()用來發送網路請求。收到回應時,先得到Response,還不是已解析的資料:

const response = await fetch(url);

console.log(response.ok);
console.log(response.status);

ok表示狀態碼是否在成功範圍,status則是實際狀態碼。收到 404 或 500 時,fetch()仍可能正常回傳Response,所以要自己檢查:

if (!response.ok) {
  throw new Error(`HTTP ${response.status}`);
}

https://ithelp.ithome.com.tw/upload/images/20261011/20178696dHJp7ULi1w.png

接著依照回應內容選擇解析方法。json()解析 JSON,text()則取得一般文字,兩者都會回傳 Promise:

const data = await response.json();
// const text = await response.text();

https://ithelp.ithome.com.tw/upload/images/20261011/201786966AOmMds4CG.png

同一份回應內容通常只能讀取一次,不能先呼叫json()後再呼叫text()。如果只是要比較兩種結果,可以先使用response.clone()複製回應。

多個工作互相依賴時,可以逐一await;互不依賴時則使用Promise.all()同時等待:

const [first, second] = await Promise.all([
  fetch(firstUrl),
  fetch(secondUrl),
]);

https://ithelp.ithome.com.tw/upload/images/20261011/20178696jQSVSrb267.png


上一篇
Day26 Promise
下一篇
Day28
系列文
從頭開始的Javascript學習之旅 共 30 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言